package com.manage.common.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
@Component
public class JwtUtil {
    // 从配置文件读取密钥（推荐）
//    @Value("${jwt.secret-key}")
    private String secretKey="3a7bFc9XkLp2zYq5vT8wE1rN4tO6uI7jK9mH0oP2xQ";

    // 缓存密钥对象
    private SecretKey cachedSecretKey;

    // 过期时间（默认1小时）
    private static final long EXPIRATION = 3600000;

    /**
     * 获取密钥对象（懒加载）
     */
    private SecretKey getSecretKey() {
        if (cachedSecretKey == null) {
            // 确保密钥长度足够（HS256 需要至少 256 位）
            if (secretKey.getBytes(StandardCharsets.UTF_8).length < 32) {
                throw new IllegalArgumentException("JWT 密钥必须至少 256 位（32 字节）");
            }
            cachedSecretKey = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
        }
        return cachedSecretKey;
    }

    /**
     * 生成 Token
     */
    public String generateToken(String subject) {
        return Jwts.builder()
                .setSubject(subject)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
                .signWith(getSecretKey(), SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * 解析 Token（增强异常处理）
     */
    public Claims parseToken(String token) {
        try {
            return Jwts.parserBuilder()
                    .setSigningKey(getSecretKey())
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
        } catch (ExpiredJwtException e) {
            throw new RuntimeException("Token 已过期", e);
        } catch (UnsupportedJwtException e) {
            throw new RuntimeException("不支持的 Token 格式", e);
        } catch (MalformedJwtException e) {
            throw new RuntimeException("Token 格式错误", e);
        } catch (SignatureException e) {
            throw new RuntimeException("Token 签名验证失败", e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("Token 参数非法", e);
        } catch (Exception e) {
            throw new RuntimeException("Token 解析失败", e);
        }
    }

    /**
     * 从 Token 中获取用户名
     */
    public String getUsernameFromToken(String token) {
        return parseToken(token).getSubject();
    }

    /**
     * 检查 Token 是否过期
     */
    public boolean isTokenExpired(String token) {
        return parseToken(token).getExpiration().before(new Date());
    }
}
